<script lang="ts">
import {defineComponent, computed, ComputedRef, ref, UnwrapRef, Ref} from "vue"
import {useCloseMessageBox} from "@/hooks/DialogMsg"
import {CreateKey} from "@/units/system"
import {ConfigType, ResourceLibraryType} from "@/components/ResourceLibrary/config";
import type {PropType} from "vue"
import UploadProgress from "./UploadProgress.vue"
import {UploadConfigType} from "@/units/upload";

/**
 * 上传选择文件
 */
export default defineComponent({
  components: {UploadProgress},
  emits: {
    close: () => true
  },
  props: {
    placeholder: {
      type: String
    },
    limit: {//选择数量
      type: Number,
      default: 100
    },
    type: {
      type: String as PropType<ResourceLibraryType>,
      required: true
    },
    conf: {//资源配置
      type: Object as PropType<ConfigType>,
      required: true
    },
    uploadConf: {//上传配置
      type: Object as PropType<UploadConfigType>,
      required: true
    },
    classify: {//资源分类
      type: Array as PropType<{ id: number, name: string }[]>,
      default: []
    }
  },
  setup(props, {emit}) {
    /**
     * 上传input实例
     */
    const input: Ref<UnwrapRef<any>> = ref(null)

    /**
     * 关闭当前实例
     */
    const close: () => void = useCloseMessageBox()


    /**
     * 关闭上传页面
     */
    function closeUpload() {
      emit('close')
      close()
    }

    /**
     * 选中文件列表
     */
    const files = ref<any[]>([])

    /**
     * 上传区KEY
     */
    const ChoiceId: ComputedRef<string> = computed(() => CreateKey())

    /**
     * 打开文件选择
     */
    function openChoiceFile() {
      input.value.value = ''
      input.value.dispatchEvent(new MouseEvent('click'))
    }

    /**
     * 上传文件选择
     * @param event
     * @constructor
     */
    async function FileChange(event: any) {
      const fileList: Array<File> = event.target.files
      for (let res of fileList) {
        files.value.push(res)
      }
    }

    /**
     * 上传实例
     * @constructor
     */
    function UploadInstance(enevt: any) {
      input.value = enevt
    }


    /**
     * 删除文件
     */
    function removeFile(index: number) {
      files.value.splice(index, 1)
    }

    /**
     * 清空选择
     */
    function clearFiles() {
      files.value = []
    }

    return {
      closeUpload,
      files,
      openChoiceFile,
      ChoiceId,
      UploadInstance,
      FileChange,
      clearFiles,
      removeFile
    }
  }
})
</script>
<template>
  <div>
    <div v-show="files.length===0" class="upload-components">
      <div class="upload-file">
        <div class="choice-file" :id="ChoiceId" @click="openChoiceFile">
          <app-icon size="80" name="UploadFilled"></app-icon>
          <el-text size="large">
            {{ placeholder ? placeholder : `选择${conf.name}或文件夹,或直接拖动文件到此处上传${conf.name}` }}
          </el-text>
          <el-text size="small" class="app-margin-top-large" type="info">
            最多选择{{ limit }}个{{ conf.name }},支持<el-text type="danger">{{ uploadConf.extention.join(',') }}格式</el-text>的{{ conf.name }}
          </el-text>
        </div>
      </div>
      <input class="app-hide" :ref="UploadInstance" @change="FileChange" type="file" multiple :accept="uploadConf.mimes"/>
    </div>
    <div v-show="files.length>0">
      <upload-progress :classify :upload-conf="uploadConf" @close="closeUpload" :files="files" :type="type" @choice="openChoiceFile" @remove="removeFile" @clear="clearFiles"></upload-progress>
    </div>
  </div>
</template>

<style scoped lang="scss">
.upload-components {
  width: 100%;
  min-height: 360px;

  .upload-file {
    width: 100%;
    min-height: 360px;

    .choice-file {
      cursor: pointer;
      display: flex;
      flex-direction: column;
      align-items: center; /* 垂直居中 */
      justify-content: center; /* 水平居中 */
      background-color: var(--el-bg-color-page);
      border-radius: 10px;
      border: 1px solid var(--el-border-color);
      box-sizing: border-box;
      margin-left: 10%;
      margin-top: 20px;
      width: 80%;
      height: 300px;
      text-align: center;

      :deep(.app-icon) {
        vertical-align: middle;
        margin-bottom: 20px;
      }
    }
  }
}
</style>